package com.hongning.railway.ui.widget;

import android.content.Context;
import android.support.v7.widget.AppCompatCheckBox;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.CheckBox;
import android.widget.CompoundButton;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class CheckBoxGroup<T> {
    private Map<CheckBox, T> checkBoxToValue;
    private Map<T, CheckBox> valueToCheckBox;
    private CheckedChangeListener<T> listener;
    private Boolean isSingle = false;

    public void setSingle(Boolean single) {
        isSingle = single;
    }


    public CheckBoxGroup(Map<CheckBox, T> checkBoxes, CheckedChangeListener<T> listener) {
        this.checkBoxToValue = checkBoxes;
        this.listener = listener;

        valueToCheckBox = new HashMap<>();
        for (Map.Entry<CheckBox, T> entry : this.checkBoxToValue.entrySet()) {
            valueToCheckBox.put(entry.getValue(), entry.getKey());

            entry.getKey().setOnCheckedChangeListener(checkedChangeListener);
        }
    }


    public void put(CheckBox checkBox, T value, boolean checked) {
        if (!checkBoxToValue.containsKey(checkBox) && !valueToCheckBox.containsKey(value)) {
            this.checkBoxToValue.put(checkBox, value);
            this.valueToCheckBox.put(value, checkBox);
            checkBox.setChecked(checked);
            listener.onCheckedChange(getValues());
            checkBox.setOnCheckedChangeListener(checkedChangeListener);
        }
    }

    public void remove(CheckBox checkBox) {
        if (checkBoxToValue.containsKey(checkBox)) {
            T value = this.checkBoxToValue.get(checkBox);
            checkBox.setOnCheckedChangeListener(null);
            this.valueToCheckBox.remove(value);
            this.checkBoxToValue.remove(checkBox);
            listener.onCheckedChange(getValues());
        }
    }

    public ArrayList<T> getValues() {
        ArrayList<T> values = new ArrayList<>();

        if (checkBoxToValue == null || checkBoxToValue.isEmpty()) {
            return values;
        }

        for (Map.Entry<CheckBox, T> entry : this.checkBoxToValue.entrySet()) {
            if (entry.getKey().isChecked()) {
                values.add(entry.getValue());
            }
        }

        return values;
    }


    public void setValues(List<T> options) {
        if (options == null) {
            for (CheckBox checkBox : checkBoxToValue.keySet()) {
                checkBox.setChecked(false);
            }
            return;
        }

        for (Map.Entry<CheckBox, T> entry : this.checkBoxToValue.entrySet()) {
            entry.getKey().setChecked(options.contains(entry.getValue()));
        }

        if (listener != null) {
            listener.onCheckedChange(getValues());
        }
    }

    public void toggleCheckBox(T value) {
        CheckBox checkBox = valueToCheckBox.get(value);
        checkBox.setChecked(!checkBox.isChecked());

        if (listener != null) {
            listener.onCheckedChange(getValues());
        }
    }

    private void setAllCheckFalse(CompoundButton buttonView ,boolean isChecked){
        if (isChecked){
            Iterator iter = valueToCheckBox.values().iterator();
            while (iter.hasNext()){
                CheckBox option = (CheckBox) iter.next();
                if (option==buttonView)continue;
                option.setChecked(false);
            }
        }


//        buttonView.setChecked(true);
    }

    private CompoundButton.OnCheckedChangeListener checkedChangeListener
            = new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isSingle){
                setAllCheckFalse(buttonView,isChecked);
            }
            if (CheckBoxGroup.this.listener != null) {
                CheckBoxGroup.this.listener.onCheckedChange(getValues());
            }
        }
    };

    /**
     * Interface to listen checkbox changes.
     *
     * <p> Checkbox group internally sets
     * {@link android.widget.CompoundButton.OnCheckedChangeListener}.
     * Do not set onCheckedChangeListener manually. Use this interface to get result
     * of CheckBox's checkedChange
     *
     * @param <T> Type of mapped value
     */
    public interface CheckedChangeListener<T> {
        void onCheckedChange(ArrayList<T> values);
    }
}
